/**
 *
 * @param {*} data --> 对象
 * @param {*} key --> 对象的属性
 * @param {*} val --> 对象属性对应的值
 *
 * defineReactive函数的作用是实现数据的响应式
 */

import observe from './observe'
import Dep from './Dep.js'

export default function defineReactive(data, key, val) {
  const dep = new Dep()
  // 如果只传俩个参数，则默认为第三个参数值为data[key]
  if (arguments.length === 2) {
    val = data[key]
  }

  // 子元素要进行observe，至此形成了递归。这个递归不是函数自己调用自己，而是多个函数、类循环调用
  let childOb = observe(val)

  Object.defineProperty(data, key, {
    // 可枚举(默认false)
    enumerable: true,
    // 可配置(默认false)
    configurable: true,

    // getter
    get() {
      console.log('你试图获取' + key + '属性')
      // 如果现在处于依赖收集阶段
      if (Dep.target) {
        dep.depend()
        if (childOb) {
          childOb.dep.depend()
        }
      }
      return val
    },
    // setter
    set(newValue) {
      console.log('你试图改变' + key + '属性', newValue)
      // 相等则不赋值
      if (val === newValue) return
      val = newValue
      // 当设置了心值，这个新值也要observe
      childOb = observe(newValue)
      // 发布订阅模式，通知dep
      dep.notify()
    },
  })
}
